/*
 * TOP SECRET Copyright 2006-2015 Transsion.com All right reserved. This software is the confidential and proprietary
 * information of Transsion.com ("Confidential Information"). You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license agreement you entered into with Transsion.com.
 */
package com.yunji.framework_template.web.controller.api;

import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.yunji.framework_template.books.orm.persistence.model.BooksUserRead;
import com.yunji.framework_template.common.web.Result;
import com.yunji.framework_template.common.web.exception.CodeException;
import com.yunji.framework_template.orm.persistence.model.Test;
import com.yunji.framework_template.orm.persistence.vo.DataDTO;
import com.yunji.framework_template.web.enums.SortOrder;
import com.yunji.framework_template.web.service.TestService;
import com.yunji.framework_template.web.service.pojo.request.TestAdd;
import com.yunji.framework_template.web.service.pojo.request.TestQueryById;
import com.yunji.framework_template.web.service.pojo.response.ResultType;
import com.yunji.framework_template.web.service.pojo.response.TestDataWrapDTO;
import com.yunji.framework_template.web.service.pojo.vo.TestWrapDTO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;

/**
 * ClassName:TestController <br/>
 * Date: 2018年9月25日 下午4:18:58 <br/>
 * 
 * @author fenglibin1982@163.com
 * @Blog http://blog.csdn.net/fenglibing
 * @version
 * @see
 */
@Slf4j
@RestController
@RequestMapping("test")
@Api(value = "Test接口", tags = "testAPI", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class TestController {

    @Autowired
    private TestService testService;

    @ApiOperation(value = "获取一条记录", notes = "仅仅获取第一条记录", httpMethod = "GET")
    @GetMapping("get1")
    public DataDTO<Test> get1() {
        return DataDTO.success(testService.findFirstBy());
    }

    @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", dataType = "String", name = "val", value = "待查询的Val的值", required = true, defaultValue = "v1") })
    @ApiOperation(value = "根据Val查询记录", notes = "传入的参数值是Val，不可以为空", httpMethod = "GET")
    @GetMapping("findByVal")
    public DataDTO<List<Test>> findByVal(String val) {
        return DataDTO.success(testService.findByVal(val));
    }

    @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", dataType = "String", name = "page", value = "当前Page的值", required = true, defaultValue = "1"),
                         @ApiImplicitParam(paramType = "query", dataType = "String", name = "size", value = "每一页的大小", required = true, defaultValue = "5"),
                         @ApiImplicitParam(paramType = "query", dataType = "String", name = "sortOrder", value = "排序字段", required = false) })
    @ApiOperation(value = "执行分页查询，并根据指定的字段排序", notes = "需要传入的参数包括必须的page,size参数和可选用于排序的字段", httpMethod = "GET")
    @GetMapping("findByPage")
    public DataDTO<Page<Test>> findByPage(int page, int size, SortOrder sortOrder) {
        return DataDTO.success(testService.findByPage(page, size, sortOrder));
    }

    @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", dataType = "String", name = "bigType", value = "bigType的值", required = true, defaultValue = "bigType1") })
    @ApiOperation(value = "根据传入的bigType查询", notes = "bigType的值不可以为空", httpMethod = "GET")
    @GetMapping("findByBigType")
    public DataDTO<List<Test>> findByBigType(String bigType) {
        return DataDTO.success(testService.findByBigType(bigType));
    }

    @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", dataType = "String", name = "bigType", value = "bigType的值", required = true, defaultValue = "bigType1"),
                         @ApiImplicitParam(paramType = "query", dataType = "String", name = "smallType", value = "smallType的值", required = true, defaultValue = "smallType1") })
    @ApiOperation(value = "根据传入的bigType和smallType查询", notes = "bigType和smallType的值都不可以为空", httpMethod = "GET")
    @GetMapping("findByBigTypeAndSmallType")
    public DataDTO<List<Test>> findByBigTypeAndSmallType(String bigType, String smallType) {
        return DataDTO.success(testService.findByBigTypeAndSmallType(bigType, smallType));
    }

    @ApiImplicitParams({ @ApiImplicitParam(paramType = "form", dataType = "String", name = "val", value = "val的值", required = true, defaultValue = "val1"),
                         @ApiImplicitParam(paramType = "form", dataType = "String", name = "bigType", value = "bigType的值", required = true, defaultValue = "bigType1"),
                         @ApiImplicitParam(paramType = "form", dataType = "String", name = "smallType", value = "smallType的值", required = true, defaultValue = "smallType1") })
    @ApiOperation(value = "增加一条记录，并返回增加成功记录的ID", notes = "需要传的的值包括val,bigType,smallType。\n注：该示例演示了简单参数的传值，参数有部分使用@ApiImplicitParam注解，有一部分没有使用的场景", httpMethod = "POST")
    @RequestMapping(value = "add", method = { RequestMethod.POST,
                                              RequestMethod.GET }, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public DataDTO<Test> add(String val, String bigType, String smallType, SortOrder sortOrder, String otherParam) {
        Test test = new Test();
        test.setBigType(bigType);
        test.setSmallType(smallType);
        test.setVal(val);
        test = testService.add(test);
        return DataDTO.success(test);
    }

    @ApiOperation(value = "增加一条记录，并返回增加成功记录的ID", notes = "需要传的的值包括val,bigType,smallType，并演示了如何自动的获取用户的IP地址", httpMethod = "POST")
    @PostMapping("add2")
    public DataDTO<Test> add2(@ApiParam(hidden = true, value = "ip的值不需要用户输入，框架会自动获取") String ip,
                        @ApiParam(value = "val的值") @NotNull @RequestBody TestAdd testAdd) {
        log.info("请求的IP为：" + ip);
        Test test = Test.builder().bigType(testAdd.getBigType()).smallType(testAdd.getSmallType()).val(testAdd.getVal()).build();
        test = testService.add(test);
        return DataDTO.success(test);
    }

    @ApiOperation(value = "返回所有的结果，不需要传入任何参数", notes = "返回的结果集可能比较大")
    @GetMapping("searchAll")
    public DataDTO<List<Test>> searchAll() {
        return DataDTO.success(testService.searchAll());
    }

    /*
     * 注：<br> 1、针对Get请求，@ApiImplicitParam的paramType使用query值；<br>
     * 2、虽然方法本身需要的Integer整型参数，但是在@ApiImplicitParam的dataType需要使用String，否则在swagger-ui界面，会在有输入数据值情况下报数据校验错误；<br>
     */
    @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", dataType = "String", name = "id", value = "id的值", required = true, defaultValue = "1") })
    @ApiOperation(value = "根据ID进行查询", notes = "传入的ID不能为空。说明：该示例演示了非对象简单参数的传值，简单参数不可以用ApiParam做注解，ApiParam用于传入Json对象的注解，简单参数用ApiImplicitParams注解")
    @GetMapping("selectById")
    public DataDTO<Test> selectById(Integer id) {
        return DataDTO.success(testService.selectById(id).orElseThrow(() -> new CodeException(HttpServletResponse.SC_NOT_FOUND)));
    }

    @ApiOperation(value = "根据ID和响应类型进行查询", notes = "说明：该示例演示了针对不同的请求类型，返回了不同的结果集，该示例使用到了ApiResponses注解做不同结果的返回")
    @ApiResponses({ @ApiResponse(code = 200, message = "success: result only include field id", response = TestDataWrapDTO.TestOnlyIdResultWrapDTO.class),
                    @ApiResponse(code = 200, message = "success: result only include fields id and val", response = TestDataWrapDTO.TestOnlyIdAndValResultWrapDTO.class),
                    @ApiResponse(code = 200, message = "success: result include all fields", response = TestDataWrapDTO.TestFullResultWrapDTO.class) })
    @GetMapping("selectByIdAndResponseType")
    public DataDTO<TestWrapDTO<? extends ResultType>> selectByIdAndResponseType(@ApiParam(value = "id的值") @NotEmpty TestQueryById testVO) {
        TestWrapDTO testWrapDTO = TestWrapDTO.of(testService.selectByIdAndResponseType(testVO));
        return DataDTO.success(testWrapDTO);
    }
	
	@RequestMapping("count")
	@ResponseBody
	public Result<Integer> count(BooksUserRead record) throws InterruptedException {
		
		return Result.success(testService.count());
	}
}
